package com.gozur.leafrecognation;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.opencv.android.Utils;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;

import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Matrix;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Toast;

public class Recognation extends Activity {
	
	protected static final String TAG = null;
	ImageButton BtnAddPic;
	ImageView ivBiner;
	ImageView ivCanny;
	
	private Uri mImageCaptureUri;
	
	private static final int PICK_FROM_CAMERA = 1;
	private static final int CROP_FROM_CAMERA = 2;
	private static final int PICK_FROM_FILE = 3;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.recognation_layout);
		InisialisasiForm();
		PilihLoad();
	}
	
	//Inisialisasi content
	private void InisialisasiForm(){
		BtnAddPic = (ImageButton) findViewById(R.id.iB_leaf);		
		ivBiner = (ImageView) findViewById(R.id.iV_Biner);
		ivCanny = (ImageView) findViewById(R.id.iV_Canny);
	}

	
	//Pilihan cara load image
	private void PilihLoad(){
		final String [] items			= new String [] {"Take from camera", "Select from gallery"};				
		ArrayAdapter<String> adapter	= new ArrayAdapter<String> (this, android.R.layout.select_dialog_item,items);
		AlertDialog.Builder builder		= new AlertDialog.Builder(this);
		
		builder.setTitle("Select Image");
		builder.setAdapter( adapter, new DialogInterface.OnClickListener() {
			public void onClick( DialogInterface dialog, int item ) { //pick from camera
				if (item == 0) {
					Intent intent 	 = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
					
					mImageCaptureUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
									   "tmp_avatar_" + String.valueOf(System.currentTimeMillis()) + ".jpg"));

					intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);

					try {
						intent.putExtra("return-data", true);
						startActivityForResult(intent, PICK_FROM_CAMERA);
					} catch (ActivityNotFoundException e) {
						e.printStackTrace();
					}
				} else { //pick from file
					Intent intent = new Intent();
	                intent.setType("image/*");
	                intent.setAction(Intent.ACTION_GET_CONTENT);
	                startActivityForResult(Intent.createChooser(intent, "Complete action using"), PICK_FROM_FILE);
				}
			}
		} );
		
		final AlertDialog dialog = builder.create();
		
		BtnAddPic.setOnClickListener(new View.OnClickListener() {	
			@Override
			public void onClick(View v) {
				dialog.show();
			}
		});
	}
	
	//Memberikan perintah pada pilihan load
	protected void onActivityResult(int requestCode, int resultCode, Intent data){
		if (resultCode != RESULT_OK) return;
		   
	    switch (requestCode) {
		    case PICK_FROM_CAMERA:
		    	doCrop();	
		    	break;
		    	
		    case PICK_FROM_FILE: 
		    	mImageCaptureUri = data.getData();
		    	doCrop();
		    	break;	    	
	    
		    case CROP_FROM_CAMERA:	    	
		        Bundle extras = data.getExtras();
		        if (extras != null) {	        	
		            Bitmap photo = extras.getParcelable("data");
		            //memanggil fungsi untuk menyisipkan image pada widget
		            SisipGambar(photo);
		        }
		        File f = new File(mImageCaptureUri.getPath());            
		        if (f.exists()) f.delete();	
		        break;
	    }
	}
	
	//fungsi untuk melakukan croping pada image
	private void doCrop() {
		final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();
    	
    	Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setType("image/*");
        
        List<ResolveInfo> list = getPackageManager().queryIntentActivities( intent, 0 );
        
        int size = list.size();
        
        if (size == 0) {	        
        	Toast.makeText(this, "Can not find image crop app", Toast.LENGTH_SHORT).show();
            return;
        } else {
        	intent.setData(mImageCaptureUri);
            
            intent.putExtra("outputX", 200);
            intent.putExtra("outputY", 200);
            intent.putExtra("aspectX", 1);
            intent.putExtra("aspectY", 1);
            intent.putExtra("scale", true);
            intent.putExtra("return-data", true);
            
        	if (size == 1) {
        		Intent i 		= new Intent(intent);
	        	ResolveInfo res	= list.get(0);
	        	i.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
	        	startActivityForResult(i, CROP_FROM_CAMERA);
        	} else {
		        for (ResolveInfo res : list) {
		        	final CropOption co = new CropOption();
		        	
		        	co.title 	= getPackageManager().getApplicationLabel(res.activityInfo.applicationInfo);
		        	co.icon		= getPackageManager().getApplicationIcon(res.activityInfo.applicationInfo);
		        	co.appIntent= new Intent(intent);
		        	
		        	co.appIntent.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
		        	
		            cropOptions.add(co);
		        }
	        
		        CropOptionAdapter adapter = new CropOptionAdapter(getApplicationContext(), cropOptions);
		        
		        AlertDialog.Builder builder = new AlertDialog.Builder(this);
		        builder.setTitle("Choose Crop App");
		        builder.setAdapter( adapter, new DialogInterface.OnClickListener() {
		            public void onClick( DialogInterface dialog, int item ) {
		                startActivityForResult( cropOptions.get(item).appIntent, CROP_FROM_CAMERA);
		            }
		        });
	        
		        builder.setOnCancelListener( new DialogInterface.OnCancelListener() {
		            @Override
		            public void onCancel( DialogInterface dialog ) {
		               
		                if (mImageCaptureUri != null ) {
		                    getContentResolver().delete(mImageCaptureUri, null, null );
		                    mImageCaptureUri = null;
		                }
		            }
		        } );
		        
		        AlertDialog alert = builder.create();
		        
		        alert.show();
        	}
        }
	} 
	
	//seting gambar yang akan disisipkan
	public void SisipGambar(Bitmap data){
		Bitmap imgNew;
		Bitmap imgBin;
		Bitmap imgBinary;
		Mat ImageCan = new Mat();
		Mat ImageBlur = new Mat();
		
		//resize gambar
		imgNew = resize(data, 100, 100);
		BtnAddPic.setImageBitmap(imgNew);
		
		//convert Bitmap to Mat
        Mat ImageMat = new Mat (imgNew.getHeight(), imgNew.getWidth(), CvType.CV_8U, new Scalar(4));
        Bitmap myBitmap32 = imgNew.copy(Bitmap.Config.ARGB_8888, true);
        Utils.bitmapToMat(myBitmap32, ImageMat);
		
        //convert to grayscale
        Imgproc.cvtColor(ImageMat, ImageMat, Imgproc.COLOR_RGB2GRAY,4);
        
        //using gaussian blur
        Imgproc.GaussianBlur(ImageMat, ImageBlur, new org.opencv.core.Size (3,3), 2, 2);
		
		//conver image menjadi binnary
        imgBin = Bitmap.createBitmap(ImageBlur.cols(), ImageBlur.rows(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(ImageBlur, imgBin);
		imgBinary = toBinary(imgBin);
		ivBiner.setImageBitmap(imgBinary);
		ivBiner.setVisibility(ImageView.VISIBLE);
		
		//convert to canny
		Imgproc.Canny(ImageBlur, ImageCan, 30, 60);

		
		//Then convert the processed Mat to Bitmap
        Bitmap resultCanny = Bitmap.createBitmap(ImageCan.cols(), ImageCan.rows(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(ImageCan, resultCanny);
        ivCanny.setImageBitmap(resultCanny);
        ivCanny.setVisibility(ImageView.VISIBLE);
	}

	
	//Keluar Aplikasi
	@Override
	public void onBackPressed() {
		AlertDialog.Builder alertDialogExit = new AlertDialog.Builder(Recognation.this);
		alertDialogExit.setTitle("Exit");
		alertDialogExit.setMessage("Are you sure?");
		alertDialogExit.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog,int which) {
				finish();
			}
		});
		alertDialogExit.setNegativeButton("No", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) { 
				dialog.cancel();
			}
		});	
		alertDialogExit.show();
	}
	
	///////////////////////////////Image Preprocesing///////////////////////////////
	
	// fungsi untuk mengubah ukuran gambar
	public Bitmap resize(Bitmap img, int Width, int Height) {
		int width = img.getWidth();
		int height = img.getHeight();
		int newWidth = (int) Width;
		int newHeight = (int) Height;

		// calculate the scale - in this case = 0.4f
		float scaleWidth = ((float) newWidth) / width;
		float scaleHeight = ((float) newHeight) / height;

		// createa matrix for the manipulation
		Matrix matrix = new Matrix();

		// resize the bit map
		matrix.postScale(scaleWidth, scaleHeight);

		// rotate the Bitmap
		// matrix.postRotate(45);

		// recreate the new Bitmap
		Bitmap resizedBitmap = Bitmap.createBitmap(img, 0, 0, width, height,
				matrix, true);

		return resizedBitmap;
	}	
	
	// fungsi untuk mengubah gambar menjadi binnary
	public Bitmap toBinary(Bitmap bmpOriginal) {
		int width, height, threshold;
		height = bmpOriginal.getHeight();
		width = bmpOriginal.getWidth();
		threshold = 127;
		Bitmap bmpBinary = Bitmap.createBitmap(bmpOriginal);

		for (int x = 0; x < width; ++x) {
			for (int y = 0; y < height; ++y) {
				// get one pixel color
				int pixel = bmpOriginal.getPixel(x, y);
				int red = Color.red(pixel);
				int green = Color.green(pixel);
				int blue = Color.blue(pixel);

				// get grayscale value
				int gray = (int) (red * 0.3 + green * 0.59 + blue * 0.11);

				// mencari nilai binary
				if (gray < threshold) {
					bmpBinary.setPixel(x, y, 0xFF000000);
				} else {
					bmpBinary.setPixel(x, y, 0xFFFFFFFF);
				}

			}
		}

		return bmpBinary;
	}	
	
	
//end
}
